package com.achievo.reportserver;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 
 * <pre>
 *  Achievo, Inc.
 *  Copyright (C): 2007
 * 
 *  Description:
 *   TODO
 *   
 *  Revision History:
 *  2007-5-31 hyman.zhang		initial version.
 * 
 * </pre>
 */

public final class MD5
{
	/**
	 * The jce MD5 message digest generator.
	 */
	private static MessageDigest md5;

	/**
	 * Retrieves a hexidecimal character sequence representing the MD5 digest of
	 * the specified character sequence, using the specified encoding to first
	 * convert the character sequence into a byte sequence. If the specified
	 * encoding is null, then ISO-8859-1 is assumed
	 * 
	 * @param string the string to encode.
	 * @param encoding the encoding used to convert the string into the byte
	 *            sequence to submit for MD5 digest
	 * @return a hexidecimal character sequence representing the MD5 digest of
	 *         the specified string
	 * @throws UnsupportedEncodingException 
	 * 
	 */
	public static final String encodeString(String string)
			throws RuntimeException, UnsupportedEncodingException
	{
//		System.out.println(digestString(string, encoding));
//		String returnValue = new String(digestString(string, encoding), "ISO-8859-1");
		return byteToHex(digestString(string, null));
//		return returnValue;
//		return StringConverter.byteToHex(digestString(string, encoding));
	}

	/**
	 * Retrieves a byte sequence representing the MD5 digest of the specified
	 * character sequence, using the specified encoding to first convert the
	 * character sequence into a byte sequence. If the specified encoding is
	 * null, then ISO-8859-1 is assumed.
	 * 
	 * @param string the string to digest.
	 * @param encoding the character encoding.
	 * @return the digest as an array of 16 bytes.
	 * 
	 */
	public static byte[] digestString(String string, String encoding)
			throws RuntimeException
	{

		byte[] data;

		if (encoding == null)
		{
			encoding = "ISO-8859-1";
		}

		try
		{
			data = string.getBytes(encoding);
		}
		catch (UnsupportedEncodingException x)
		{
			throw new RuntimeException(x.toString());
		}

		return digestBytes(data);
	}

	/**
	 * Retrieves a byte sequence representing the MD5 digest of the specified
	 * byte sequence.
	 * 
	 * @param data the data to digest.
	 * @return the MD5 digest as an array of 16 bytes.
	 * 
	 */
	public static final byte[] digestBytes(byte[] data) throws RuntimeException
	{

		synchronized (MD5.class)
		{
			if (md5 == null)
			{
				try
				{
					md5 = MessageDigest.getInstance("MD5");
				}
				catch (NoSuchAlgorithmException e)
				{
					throw new RuntimeException(e.toString());
				}
			}

			return md5.digest(data);
		}
	}
	
	public static String byteToHex(byte[] bs)
	{
		char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };
		StringBuffer str = new StringBuffer();
		for (int i = 0; i < bs.length; i++)
		{
			char[] array = { hexDigit[(bs[i] >> 4) & 0x0f], hexDigit[bs[i] & 0x0f] };
			str.append(array);
		}
		
		
		
		return str.toString();
	}
	
	
	
	public static void main(String[] args) throws UnsupportedEncodingException, RuntimeException
	{
		System.out.println("admin" +"\t:\t" + encodeString("admin"));
		System.out.println("hyman" +"\t:\t"  + encodeString("hyman"));
		System.out.println("Hyman" +"\t:\t"  + encodeString("Hyman"));
		System.out.println("abc" +"\t:\t"  + encodeString("abc"));
		System.out.println("abc" +"\t:\t"  + encodeString("5"));
	}
	
	

//	private static String charToHex(char c)
//	{
//		// Returns hex String representation of char c
//		byte hi = (byte) (c >>> 8);
//		byte lo = (byte) (c & 0xff);
//		return byteToHex(hi) + byteToHex(lo);
//	}


}
